﻿
/*=========================================
* Author: VIP
* Description: UITree/TreeView.UITreeData
* UITreeData is equivalent to the MVC Model layer, only used to save the data.
==========================================*/

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VIPUITreeData {

    #region members && constructor

    public VIPUITreeData Parent;
    public List<VIPUITreeData> ChildNodes;
    public int Layer = 0;
    public string Name = String.Empty;

    public VIPUITreeData() { }
    public VIPUITreeData(string name, int layer = 0)
    {
        Name = name;
        Layer = layer;
        Parent = null;
        ChildNodes = new List<VIPUITreeData>();
    }
    public VIPUITreeData(string name, List<VIPUITreeData> childNodes, int layer = 0)
    {
        Name = name;
        Parent = null;
        ChildNodes = childNodes;
        if (null == ChildNodes)
            ChildNodes = new List<VIPUITreeData>();
        Layer = layer;
        ResetChildren(this);
    }

    #endregion

    #region operator methods

    public void SetParent(VIPUITreeData parent)
    {
        if (null != this.Parent)
            this.Parent.RemoveChild(this);
        this.Parent = parent;
        this.Layer = parent.Layer + 1;
        parent.ChildNodes.Add(this);
        ResetChildren(this);
    }

    public void AddChild(VIPUITreeData child)
    {
        AddChild(new VIPUITreeData[] { child });
    }

    public void AddChild(IEnumerable<VIPUITreeData> children)
    {
        foreach (VIPUITreeData child in children)
            child.SetParent(this);
    }

    public void RemoveChild(VIPUITreeData child)
    {
        RemoveChild(new VIPUITreeData[] { child });
    }

    public void RemoveChild(IEnumerable<VIPUITreeData> children)
    {
        foreach (VIPUITreeData child in children)
        {
            for (int i = 0; i < ChildNodes.Count; i++)
                if (child == ChildNodes[i])
                {
                    ChildNodes.Remove(ChildNodes[i]);
                    break;
                }
        }
    }

    public void ClearChildren()
    {
        ChildNodes = null;
    }

    private void ResetChildren(VIPUITreeData treeData)
    {
        for (int i = 0; i < treeData.ChildNodes.Count; i++)
        {
            VIPUITreeData node = treeData.ChildNodes[i];
            node.Parent = treeData;
            node.Layer = treeData.Layer + 1;
            ResetChildren(node);
        }
    }

    #endregion

    #region override functions

    public override bool Equals(object obj)
    {
        VIPUITreeData other = obj as VIPUITreeData;
        if (null == other) return false;
        return other.Name.Equals(Name) && other.Layer.Equals(Layer);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = (Parent != null ? Parent.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (ChildNodes != null ? ChildNodes.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ Layer;
            hashCode = (hashCode * 397) ^ (Name != null ? Name.GetHashCode() : 0);
            return hashCode;
        }
    }

    #endregion

}
